package pl.pw.eiti.mkoi.squfof;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


public class FactorSqufofActivity extends Activity {
	
	private enum OperationType {
		NONE,
		ADDITION,
		SUBTRACTION,
		MULTIPLICATION,
		DIVISION
	}
	
	private OperationType mActiveOperation;
	private Integer mCurrentValue;
	
	private boolean mLastActionWasOperation = true;
	
	@SuppressWarnings("unused")
	private static final String LOG_TAG = FactorSqufofActivity.class.getSimpleName();
	
	private TextView mTextViewCurrentValue;
	private TextView mTextViewCurrentOperation;
	private TextView mTextViewStoredValue;
	
	private Calculator mCalculator;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // factorisation
        ((Button)findViewById(R.id.button_factorise)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				factoriseAndUpdate();
			}
		});
        
        // numbers' buttons
        ((Button)findViewById(R.id.button_1)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				addDigitAndUpdate(1);
			}
		});
        ((Button)findViewById(R.id.button_2)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				addDigitAndUpdate(2);
			}
		});
        ((Button)findViewById(R.id.button_3)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	addDigitAndUpdate(3);
            }
        });
        ((Button)findViewById(R.id.button_4)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	addDigitAndUpdate(4);
            }
        });
        ((Button)findViewById(R.id.button_5)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	addDigitAndUpdate(5);
            }
        });
        ((Button)findViewById(R.id.button_6)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	addDigitAndUpdate(6);
            }
        });
        ((Button)findViewById(R.id.button_7)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	addDigitAndUpdate(7);
            }
        });
        ((Button)findViewById(R.id.button_8)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	addDigitAndUpdate(8);
            }
        });
        ((Button)findViewById(R.id.button_9)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	addDigitAndUpdate(9);
            }
        });
        ((Button)findViewById(R.id.button_0)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	addDigitAndUpdate(0);
            }
        });
        // operations' buttons
        ((Button)findViewById(R.id.button_add)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				setOperationAndUpdate(OperationType.ADDITION);
			}
		});
        ((Button)findViewById(R.id.button_subtract)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				setOperationAndUpdate(OperationType.SUBTRACTION);
			}
		});
        ((Button)findViewById(R.id.button_multiply)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				setOperationAndUpdate(OperationType.MULTIPLICATION);
			}
		});
        ((Button)findViewById(R.id.button_divide)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				setOperationAndUpdate(OperationType.DIVISION);
			}
		});
        
        ((Button)findViewById(R.id.button_delete)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				removeDigitAndUpdate();
			}
		});
        
        ((Button)findViewById(R.id.button_equals)).setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				showResult();
			}
		});
        
        // other laoput components
        mTextViewCurrentValue = (TextView)findViewById(R.id.textView_currentValueDisplay);
        mTextViewCurrentOperation = (TextView)findViewById(R.id.textView_currentOperationDisplay);
        mTextViewStoredValue = (TextView)findViewById(R.id.textView_storedValueDisplay);
        
        // calculator
        mCalculator = new Calculator();
        
        // init?
        mActiveOperation = OperationType.NONE;
        mCurrentValue = 0;
    }
    
    private void factoriseAndUpdate() {
		factorise();
		updateViewedText();
		
		mLastActionWasOperation = false;
    }
    
    private void removeDigitAndUpdate() {
		removeLastDigit();
		updateViewedText();
		
		mLastActionWasOperation = false;
    }
    
    private void showResult() {
    	doOperation();
    	updateViewedText();
    	
		mLastActionWasOperation = false;
    }
    
    private void doOperation() {
		switch (mActiveOperation) {
		case ADDITION:
			mCalculator.add(mCurrentValue);
			break;
		case SUBTRACTION:
			try {
				mCalculator.subtract(mCurrentValue);
			} catch (ArithmeticException e) {
				Toast.makeText(this, "Nieujemnym wynikiem odejmowania jest 0!", Toast.LENGTH_SHORT).show();
				mCalculator.setValue(0);
			}
			break;
		case MULTIPLICATION:
			mCalculator.multiply(mCurrentValue);
			break;
		case DIVISION:
			try {
				mCalculator.divide(mCurrentValue);
			} catch (ArithmeticException e) {
				Toast.makeText(this, "Nie można dzielić przez 0!", Toast.LENGTH_SHORT).show();
			}
			break;
		case NONE:
			try {
				mCalculator.setValue(mCurrentValue);
			} catch (ArithmeticException e) {
				Toast.makeText(this, "Nie wolno podawać ujemnych liczb. Ustawiono wartość 0", Toast.LENGTH_SHORT).show();
				mCalculator.setValue(0);
			}
		default:
			break;
   		}
		
		mCurrentValue = mCalculator.getValue();
		
		mActiveOperation = OperationType.NONE;
    }
    
    private void setOperationAndUpdate(OperationType operation) {
    	if (!mLastActionWasOperation) doOperation();
    	
		mActiveOperation = operation;
		updateViewedText();
		
		mLastActionWasOperation = true;
    }
    
    private void addDigitAndUpdate(int digit) {
    	if (mLastActionWasOperation) {
    		mCurrentValue = 0;
    	}
    	
    	try {
    		addDigit(digit);
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
        updateViewedText();
        
        mLastActionWasOperation = false;
    }
    
    private void updateViewedText() {
    	// operation
    	switch (mActiveOperation) {
    	case ADDITION:
    		mTextViewCurrentOperation.setText("  " + getString(R.string.button_add_text));
    		break;
    	case SUBTRACTION:
    		mTextViewCurrentOperation.setText("  " + getString(R.string.button_subtract_text));
    		break;
    	case MULTIPLICATION:
    		mTextViewCurrentOperation.setText("  " + getString(R.string.button_multiply_text));
    		break;
    	case DIVISION:
    		mTextViewCurrentOperation.setText("  " + getString(R.string.button_divide_text));
    		break;
    	default:
    		mTextViewCurrentOperation.setText("  " + getString(R.string.button_none_text));
    		break;
    	} 
    	
    	// value
    	mTextViewCurrentValue.setText(mCurrentValue.toString());
    	mTextViewStoredValue.setText(mCalculator.getValue().toString());
    }
    
    private void factorise() {
		try {
			mCalculator.setValue(mCurrentValue);
		} catch (ArithmeticException e) {
			Toast.makeText(this, "Nie wolno podawać ujemnych liczb. Ustawiono wartość 0", Toast.LENGTH_SHORT).show();
			mCalculator.setValue(0);
		}
    	updateViewedText();
		mCurrentValue = mCalculator.getFactor();
    }
    
    private void addDigit(int digit) throws Exception {
    	if (digit > 9 || digit < 0) throw new Exception("Niepoprawna cyfra: "+digit);
		mCurrentValue = mCurrentValue*10 + digit;
    }
    
    private void removeLastDigit() {
    	mCurrentValue /= 10;
    }
}